iT邦幫忙

2022 iThome 鐵人賽

DAY 16
0

今天來繼續函數,廢話不多說直接開始。

函數類型

每個函數都有特定的類型,函數的類型都是由參數跟返回值所組成的。

官方有兩個簡單的例子

func addTwoInts(_ a: Int, _ b: Int) -> Int {
    return a + b
}
func multiplyTwoInts(_ a: Int, _ b: Int) -> Int {
    return a * b
}
func printHelloWorld() {
    print("hello, world")
}

第一個的類型就是兩個參數返回一個類型的值 (Int, Int) -> Int。
第二個就是沒有返回值也沒有參數 () -> Void

使用函數類型

使用函數類型就像使用其他類型一樣,我們看一下官方的例子

var mathFunction: (Int, Int) -> Int = addTwoInts

此處的 addTwoInts 是上面的那一個函數

func addTwoInts(_ a: Int, _ b: Int) -> Int {
    return a + b
}

所以定義了一個 mathFunction 的變量,類型是 跟上面第一個類型一樣,兩個參數返回一個 Int 的值,並讓這個變量指向 addTwoInts 函數。
這樣兩個同 Type 的東西 可以相等了,所以 mathFunction 會使用 addTwoInts 裡面的方法。

print("Result: \(mathFunction(2, 3))")
// Prints "Result: 5"

有相同函數類型,但給不同的函數賦值給同一個變量就可以使用該函數的方法。

mathFunction = multiplyTwoInts
print("Result: \(mathFunction(2, 3))")
// Prints "Result: 6"

函數類型作為參數類型

函數也可以作為參數設在另一個函數裡面,來看一下官方的例子。

func printMathResult(_ mathFunction: (Int, Int) -> Int, _ a: Int, _ b: Int) {
    print("Result: \(mathFunction(a, b))")
}
printMathResult(addTwoInts, 3, 5)
// 打印“Result: 8”

這個官方的例子裡面 printMathResult(::_:) 函數,它有三個參數:第一個參數叫 mathFunction,類型是 (Int, Int) -> Int,你可以傳入任何這種類型的函數;第二個和第三個參數叫 a 和 b,它們的類型都是 Int,這兩個值作為已給出的函數的輸入值。

然後調用 printMathResult 時,他帶被傳入 addTwoInts 函數並帶入參數 3,5 輸出結果就會為 8 。

printMathResult(:::) 這個函數就是輸出另一個適當的類型的數學函數,不回關心傳入函數怎樣完成的,只在乎是不是正確的類型。
這種書寫方式是一種類型安全(type-safe) 的方式。

函數類型作為返回類型

就是函數的返回類型,也是函數。就來看官方的例子吧。

先定義兩個函數,分別是 stepForward(:) 和 stepBackward(:)。

func stepForward(_ input: Int) -> Int {
    return input + 1
}
func stepBackward(_ input: Int) -> Int {
    return input - 1
}

再來是返回函數的例子,下面有用到前面基本運算符提到的 三元運算符。

func chooseStepFunction(backward: Bool) -> (Int) -> Int {
    return backward ? stepBackward : stepForward
}

var currentValue = 3
let moveNearerToZero = chooseStepFunction(backward: currentValue > 0)
// moveNearerToZero 现在指向 stepBackward() 函数。

他在 chooseStepFunction 裡面,先設置了判別,然後在拿到返回的函數,進而在拿到最後的返回值。
return 裡面的三元運算符,很明白的寫道,如果 backward 成立則拿到 stepBackward ,如果不成立就拿到 stepForward 。

所以依照上面的法子可以做一個倒數到 0 的函數。

print("Counting to zero:")
// Counting to zero:
while currentValue != 0 {
    print("\(currentValue)... ")
    currentValue = moveNearerToZero(currentValue)
}
print("zero!")
// 3...
// 2...
// 1...
// zero!

嵌套函數

到目前為止前面介紹的都是 全局函數(global functions),他們定義在全局域中。所以 嵌套函數 就是把他們定義在函數中。
依照如此說可以改寫上面 chooseStepFunction(backward:)函數。

func chooseStepFunction(backward: Bool) -> (Int) -> Int {
    func stepForward(input: Int) -> Int { return input + 1 }
    func stepBackward(input: Int) -> Int { return input - 1 }
    return backward ? stepBackward : stepForward
}
var currentValue = -4
let moveNearerToZero = chooseStepFunction(backward: currentValue > 0)
// moveNearerToZero now refers to the nested stepForward() function
while currentValue != 0 {
    print("\(currentValue)... ")
    currentValue = moveNearerToZero(currentValue)
}
print("zero!")
// -4...
// -3...
// -2...
// -1...
// zero!

好了,今天終於把函數看完了,明天繼續往下看。


上一篇
30天的 iOS 修仙道路 (15)
下一篇
30天的 iOS 修仙道路 (17)
系列文
30天的 iOS 修仙道路 站穩腳步基礎篇30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言